﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using MCMLXVII.BackEnd.Services.OrganizationChart.Messages;
using MCMLXVII.BackEnd.Data.OrganizationChart;
using MCMLXVII.BackEnd.Services.Common.Messages;
using MCMLXVII.BackEnd.Pipeline;
using MCMLXVII.BackEnd.Data.SystemDatabase;
using MCMLXVII.Core.Common.BackEnd;
using MCMLXVII.BackEnd.Data.OrganizationChart.DataSets;
using MCMLXVII.Core.Common;

#endregion

namespace MCMLXVII.BackEnd.Services.OrganizationChart.BusinessActions
{
    public class OrganizationTree
    {

        #region Auxiliar Functions
        private static msgOrganizationNodeInfo GetFatherNode(msgOrganizationNodeInfo Root, int NodeID)
        {
            if (Root == null)
            {
                return null;
            }
            else
            {
                if (Root.NodeID == NodeID)
                {
                    return Root;
                }
                else
                {
                    if (Root.FirstChild == null)
                    {
                        if (Root.NextBrother == null)
                        {
                            return null;
                        }
                        else
                        {
                            return GetFatherNode(Root.NextBrother, NodeID);
                        }
                    }
                    else
                    {
                        msgOrganizationNodeInfo AuxNode = GetFatherNode(Root.FirstChild, NodeID);
                        if (AuxNode != null)
                        {
                            return AuxNode;
                        }
                        else
                        {
                            if (Root.NextBrother == null)
                            {
                                return null;
                            }
                            else
                            {
                                return GetFatherNode(Root.NextBrother, NodeID);
                            }
                        }
                    }
                }
            }

        }
        #endregion

        /// <summary>
        /// Implements Action GetOrganizationTree
        /// </summary>
        public static msgOrganizationNodeInfo GetOrganizationTree(msgVoidRequest req)
        {
            int MemberID = Security.GetMemberIDFromSession();
            int Translations;
            int i;
            string UserLang = MultiLingualContents.GetMemberLanguage(MemberID);
            msgOrganizationNodeInfo Root = new msgOrganizationNodeInfo();
            DSorganizationTreeNode ds = TreeAndNodes.GetTree(MemberID);
            if (ds != null) 
            {

                foreach (DSorganizationTreeNode.OrganizationTreeRow row in ds.OrganizationTree.Rows)
                {
                    if (row.NodeID == 1)
                    {
                        Root.NodeID = 1;
                        Root.Name = row.Name;
                        Root.BlockInheritance = (row.BlockInheritance == "Y");
                        Root.UpdateSequence = row.UpdSequence;
                        Root.DirectoryConfigInfo = row.IsDirectoryServiceConfigInfoNull() ? "" : row.DirectoryServiceConfigInfo;
                        //if (!row.IsDirectoryServiceConfigInfoNull())
                        //{
                        //    System.Data.SqlTypes.SqlXml sqlx = new System.Data.SqlTypes.SqlXml(row.DirectoryServiceConfigInfo);
                        //    XmlDocument xdoc = new XmlDocument();
                        //    xdoc.Load(sqlx.CreateReader());
                        //    Root.DirectoryConfigInfo = xdoc.OuterXml;
                        //}
                        Root.OwnerID = row.OwnerID;
                        Root.FatherID = 0;
                        Translations = 0;
                        foreach (DSorganizationTreeNode.OrganizationTreeXLatedRow trans in row.GetChildRows("FK_Translations"))
                        {
                            if (trans.Language != UserLang)
                                Translations++;
                        }
                        if (Translations > 0)
                        {
                            i = 0;
                            NodeLanguageTranslations[] ArrTrans = new NodeLanguageTranslations[Translations];
                            foreach (DSorganizationTreeNode.OrganizationTreeXLatedRow trans in row.GetChildRows("FK_Translations"))
                            {
                                if (trans.Language != UserLang)
                                {
                                    ArrTrans[i] = new NodeLanguageTranslations();
                                    ArrTrans[i].Language = trans.Language;
                                    ArrTrans[i].Name = trans.Name;
                                    i++;
                                }
                            }
                            Root.Translations = ArrTrans;
                        }
                    }
                    else
                    {
                        msgOrganizationNodeInfo node = new msgOrganizationNodeInfo();
                        node.NodeID = row.NodeID;
                        node.Name = row.Name;
                        node.BlockInheritance = (row.BlockInheritance == "Y");
                        node.UpdateSequence = row.UpdSequence;
                        node.DirectoryConfigInfo = row.IsDirectoryServiceConfigInfoNull() ? "" : row.DirectoryServiceConfigInfo;
                        //if (!row.IsDirectoryServiceConfigInfoNull())
                        //{
                        //    System.Data.SqlTypes.SqlXml sqlx = new System.Data.SqlTypes.SqlXml(row.DirectoryServiceConfigInfo);
                        //    XmlDocument xdoc = new XmlDocument();
                        //    xdoc.Load(sqlx.CreateReader());
                        //    node.DirectoryConfigInfo = xdoc.OuterXml;
                        //}
                        node.OwnerID = row.OwnerID;
                        node.FatherID = row.FatherNodeID;
                        Translations = 0;
                        foreach (DSorganizationTreeNode.OrganizationTreeXLatedRow trans in row.GetChildRows("FK_Translations"))
                        {
                            if (trans.Language != UserLang)
                                Translations++;
                        }
                        if (Translations > 0)
                        {
                            i = 0;
                            NodeLanguageTranslations[] ArrTrans = new NodeLanguageTranslations[Translations];
                            foreach (DSorganizationTreeNode.OrganizationTreeXLatedRow trans in row.GetChildRows("FK_Translations"))
                            {
                                if (trans.Language != UserLang)
                                {
                                    ArrTrans[i] = new NodeLanguageTranslations();
                                    ArrTrans[i].Language = trans.Language;
                                    ArrTrans[i].Name = trans.Name;
                                    i++;
                                }
                            }
                            node.Translations = ArrTrans;
                        }
                        msgOrganizationNodeInfo FatherNode = GetFatherNode(Root, node.FatherID);
                        if (FatherNode.FirstChild == null)
                        {
                            FatherNode.FirstChild = node;
                        }
                        else
                        {
                            FatherNode = FatherNode.FirstChild;
                            while (FatherNode.NextBrother != null)
                            {
                                FatherNode = FatherNode.NextBrother;
                            }
                            FatherNode.NextBrother = node;
                        }
                    }
                }
            }
            return Root;
        }


        public static msgOrganizationNodeInfo GetOrganizationTreeFromNode(msgGenericItemRequest<int> req)
        {
            int MemberID = Security.GetMemberIDFromSession();
            //int i;
            string UserLang = MultiLingualContents.GetMemberLanguage(MemberID);
            msgOrganizationNodeInfo Root = new msgOrganizationNodeInfo();
            DSorganizationTreeNode.OrganizationTreeDataTable dt = TreeAndNodes.GetTreeFromNode(req.Item,  MemberID);
            if (dt != null)
            {

                foreach (DSorganizationTreeNode.OrganizationTreeRow row in dt.Rows)
                {
                    if (row.NodeID == req.Item )
                    {
                        Root.NodeID = req.Item ;
                        Root.Name = row.Name;
                        Root.BlockInheritance = (row.BlockInheritance == "Y");
                        Root.UpdateSequence = row.UpdSequence;
                        Root.OwnerID = row.OwnerID;
                        Root.FatherID = 0;
                    }
                    else
                    {
                        msgOrganizationNodeInfo node = new msgOrganizationNodeInfo();
                        node.NodeID = row.NodeID;
                        node.Name = row.Name;
                        node.BlockInheritance = (row.BlockInheritance == "Y");
                        node.UpdateSequence = row.UpdSequence;
                        node.OwnerID = row.OwnerID;
                        node.FatherID = row.FatherNodeID;
                        msgOrganizationNodeInfo FatherNode = GetFatherNode(Root, node.FatherID);
                        if (FatherNode.FirstChild == null)
                        {
                            FatherNode.FirstChild = node;
                        }
                        else
                        {
                            FatherNode = FatherNode.FirstChild;
                            while (FatherNode.NextBrother != null)
                            {
                                FatherNode = FatherNode.NextBrother;
                            }
                            FatherNode.NextBrother = node;
                        }
                    }
                }
            }
            return Root;
        }




        public static msgOrganizationNodeInfo GetOrganizationTreeNodeInfo(msgSimpleNodeRequest req)
        {
            int MemberID = Security.GetMemberIDFromSession();
            int Translations;
            int i;
            string UserLang = MultiLingualContents.GetMemberLanguage(MemberID);
            msgOrganizationNodeInfo Root = new msgOrganizationNodeInfo();
            DSorganizationTreeNode ds = TreeAndNodes.GetOrganizationTreeNodeInfo( req.NodeID, MemberID);
            DSorganizationTreeNode.OrganizationTreeRow row = (DSorganizationTreeNode.OrganizationTreeRow)ds.Tables["OrganizationTree"].Rows[0];
            Root.NodeID = req.NodeID;
            Root.Name = row.Name;
            Root.BlockInheritance = (row.BlockInheritance == "Y");
            Root.UpdateSequence = row.UpdSequence;
            Root.DirectoryConfigInfo = row.IsDirectoryServiceConfigInfoNull() ? "" : row.DirectoryServiceConfigInfo; 
            //if (!row.IsDirectoryServiceConfigInfoNull())
            //{
            //    System.Data.SqlTypes.SqlXml sqlx = new System.Data.SqlTypes.SqlXml(row.DirectoryServiceConfigInfo);
            //    XmlDocument xdoc = new XmlDocument();
            //    xdoc.Load(sqlx.CreateReader());
            //    Root.DirectoryConfigInfo = xdoc.OuterXml;
            //}
            Root.OwnerID = row.OwnerID;
            Root.FatherID = row.FatherNodeID;
            Translations = 0;
            foreach (DSorganizationTreeNode.OrganizationTreeXLatedRow trans in row.GetChildRows("FK_Translations"))
            {
                if (trans.Language != UserLang)
                    Translations++;
            }
            if (Translations > 0)
            {
                i = 0;
                NodeLanguageTranslations[] ArrTrans = new NodeLanguageTranslations[Translations];
                foreach (DSorganizationTreeNode.OrganizationTreeXLatedRow trans in row.GetChildRows("FK_Translations"))
                {
                    if (trans.Language != UserLang)
                    {
                        ArrTrans[i] = new NodeLanguageTranslations();
                        ArrTrans[i].Language = trans.Language;
                        ArrTrans[i].Name = trans.Name;
                        i++;
                    }
                }
                Root.Translations = ArrTrans;
            }
            return Root;
        }

        
        
        /// <summary>
        /// Implements Action GetOrganizationTree
        /// </summary>
        public static msgOrganizationNodeInfo GetOrganizationDestinationTree(msgSimpleNodeRequest  req)
        {
            int MemberID = Security.GetMemberIDFromSession();
            msgOrganizationNodeInfo Root = new msgOrganizationNodeInfo();
            DSorganizationTreeNode ds = TreeAndNodes.GetDestinationTree(MemberID, req.NodeID );
            if (ds != null)
            {

                foreach (DSorganizationTreeNode.OrganizationTreeRow row in ds.OrganizationTree.Rows)
                {
                    if (row.NodeID == 1)
                    {
                        Root.NodeID = 1;
                        Root.Name = row.Name;
                        Root.FatherID = 0;
                    }
                    else
                    {
                        msgOrganizationNodeInfo node = new msgOrganizationNodeInfo();
                        node.NodeID = row.NodeID;
                        node.Name = row.Name;
                        node.FatherID = row.FatherNodeID;
                        msgOrganizationNodeInfo FatherNode = GetFatherNode(Root, node.FatherID);
                        if (FatherNode.FirstChild == null)
                        {
                            FatherNode.FirstChild = node;
                        }
                        else
                        {
                            FatherNode = FatherNode.FirstChild;
                            while (FatherNode.NextBrother != null)
                            {
                                FatherNode = FatherNode.NextBrother;
                            }
                            FatherNode.NextBrother = node;
                        }
                    }
                }
            }
            return Root;
        }

        /// <summary>
        /// Implements Action GetOrganizationTreeNodeEfectiveRights
        /// </summary>
        public static string[] GetOrganizationTreeNodeEfectiveRights(msgSimpleNodeRequest  Node)
        {
            int MemberID = Security.GetMemberIDFromSession();
            return TreeAndNodes.GetOrganizationTreeNodeEfectiveRights(Node.NodeID, MemberID );

        }

        /// <summary>Implements Action GetOrganizationTreeNodeAudit</summary>
        public static msgOrganizationNodeAuditInfo[] GetOrganizationTreeNodeAudit(msgSimpleNodeRequest req)
        {
            // Load Members Classes
            int MemberID = Security.GetMemberIDFromSession();
            DSOrganizationAudit.TreeNodeAuditDataTable dt = TreeAndNodes.GetOrganizationTreeNodeAudit(req.NodeID);
            msgOrganizationNodeAuditInfo[] response = new msgOrganizationNodeAuditInfo[dt.Rows.Count];
            int i = 0;
            foreach (DSOrganizationAudit.TreeNodeAuditRow row in dt.Rows)
            {
                response[i] = new msgOrganizationNodeAuditInfo(row.NodeID, row.Name, row.FatherNodeID, row.OwnerID, (row.BlockInheritance=="Y"), "TODO", row.Operation, row.DateAndTime, row.ExecutedByMemberID, row.Description);
                i++;
            }
            return response;
        }

        /// <summary>Implements action CreateNewOrganizationTreeNode</summary>
        public static msgNewOrganizationTreeItemResponse CreateNewOrganizationTreeNode(msgNewOrganizationTreeNode req)
        {
            int RequestingMemberID = Security.GetMemberIDFromSession();
            DSOrganizationTreeNewItem.NewCreatedItemRow dr = TreeAndNodes.CreateNewOrganizationTreeNode(req.NodeID, RequestingMemberID, req.TempNodeName);
            if (dr == null)
                return null;
            else
            {
                if (req.NodeID == 1)
                    FirstLevelNodeCreated(Convert.ToInt32(dr.Identity));
                return new msgNewOrganizationTreeItemResponse(Convert.ToInt32(dr.Identity), dr.UpdateSequence);
            }
        }

        private static void FirstLevelNodeCreated(int NodeID)
        {
            //string lUrl = Configuration.Instance.GetSystemParameter("WSStorage");
            //string lPrefix = Configuration.Instance.GetSystemParameter("SitePrefix");
            //string lTemp = Configuration.Instance.GetSystemParameter("SiteTemplate");
            //WSStorage.Storage ws = new WSStorage.Storage();
            //ws.Url = lUrl;
            //ws.Credentials = System.Net.CredentialCache.DefaultCredentials;
            //WSStorage.Location loc = ws.CreateSite(lPrefix + NodeID.ToString(), NodeID.ToString(), lTemp);

            //TreeAndNodes.UpdateOrganizationTreeNodeProperty(NodeID, "Site", loc.ToString());
            //loc.ToString(); //Url del sitio
            
            //ToDo: grabar la Url del sitio
        }

        /// <summary>Implements action UpdateOrganizationTreeNode</summary>
        public static int UpdateOrganizationTreeNode(msgUpdateOrganizationTreeNode req)
        {
          int RequestingMemberID = Security.GetMemberIDFromSession();
          //Obtain User & Default Language
          string UserLang = MultiLingualContents.GetMemberLanguage(RequestingMemberID);
          string DefaultLang = MultiLingualContents.GetDefaultLanguage();
          string NodeName = "";
          if ((UserLang == DefaultLang) ||(req.Translations == null))
              NodeName = req.Name;
          else
          {
              NodeName = req.Name;
              foreach (NodeLanguageTranslations node in req.Translations)
              {
                  if (node.Language == DefaultLang)
                  {
                      NodeName = node.Name;
                      break;
                  }
              }
              if (NodeName == "")
                  NodeName = req.Name;
          }

          StringBuilder sb = new StringBuilder();
          sb.Append("<Translations>");
          if (req.Translations != null)
          {
              foreach (NodeLanguageTranslations node in req.Translations)
              {
                  if (node.Language != DefaultLang)
                  {
                      sb.Append("<Translation><Language>" + node.Language + "</Language><Name>" + node.Name + "</Name></Translation>");
                  }
              }
          }
          sb.Append("</Translations>");
          return TreeAndNodes.UpdateOrganizationTreeNode(req.NodeID, NodeName, req.FatherID, req.DirectoryConfigInfo, req.UpdateSequence, sb.ToString(), RequestingMemberID);
       
        }

        /// <summary>Implements action MoveOrganizationTreeNode</summary>
        public static int MoveOrganizationTreeNode(msgMoveNodeRequest req)
        {
          int RequestingMemberID = Security.GetMemberIDFromSession();
          //Obtain User & Default Language
          int tmp = TreeAndNodes.MoveOrganizationTreeNode(req.NodeID, req.DestinationNodeID, req.UpdateSequence, RequestingMemberID);
          if (req.DestinationNodeID == 1)
                  FirstLevelNodeCreated(req.NodeID);
          return tmp;

        }

        /// <summary>Implements Action DeleteOrganizationTreeNode</summary>
        public static bool DeleteOrganizationTreeNode(msgSimpleNodeRequest req)
        {
            int RequestingMemberID = Security.GetMemberIDFromSession();
            TreeAndNodes.DeleteOrganizationTreeNode(req.NodeID, RequestingMemberID);                
            return true;
        }
        
        /// <summary>Implements Action GetorganizationTreeNodeSecurity</summary>
        public static msgOrganizationTreeNodeSecurity GetOrganizationTreeNodeSecurity(msgSimpleNodeRequest req)
        {
            DSOrganizationTreeNodeSecurity ds = TreeAndNodes.GetOrganizationTreeNodeSecurity(req.NodeID);
            OrganizationTreeNodePermissions[] defined;
            OrganizationTreeNodePermissions[] inherited;
            int i;
            if (ds.OrganizationTreeNodeDefinedRights.Rows.Count > 0)
            {
                defined = new OrganizationTreeNodePermissions[ds.OrganizationTreeNodeDefinedRights.Rows.Count];
                i = 0;
                foreach (DSOrganizationTreeNodeSecurity.OrganizationTreeNodeDefinedRightsRow row in ds.OrganizationTreeNodeDefinedRights)
                {
                    defined[i] = new OrganizationTreeNodePermissions(row.MemberID, row.Description, row.MemberClass, row.Permission);
                    i++;
                }
            }
            else
            {
                defined = null;
            }
            if (ds.OrganizationTreeNodeInheritedRights.Rows.Count > 0)
            {
                inherited  = new OrganizationTreeNodePermissions[ds.OrganizationTreeNodeInheritedRights.Rows.Count];
                i = 0;
                foreach (DSOrganizationTreeNodeSecurity.OrganizationTreeNodeInheritedRightsRow row in ds.OrganizationTreeNodeInheritedRights)
                {
                    inherited[i] = new OrganizationTreeNodePermissions(row.MemberID, row.Description, row.MemberClass, row.Permission);
                    i++;
                }
            }
            else
            {
                inherited = null;
            }

            return new msgOrganizationTreeNodeSecurity(inherited, defined);                        
        }

        /// <summary>Implements Action UpdateOrganizationTreeNodeSecurity</summary>
        public static int UpdateOrganizationTreeNodeSecurity(msgUpdateOrganizationTreeNodeSecurity req)
        {
            int RequestingMemberID = Security.GetMemberIDFromSession();
            DSOrganizationTreeNodeSecurity.OrganizationTreeNodeDefinedRightsDataTable dt = new DSOrganizationTreeNodeSecurity.OrganizationTreeNodeDefinedRightsDataTable();
            foreach(OrganizationTreeNodePermissions per in req.Defined)
            {
                dt.Rows.Add( per.MemberID, per.Permission, "", 0);
                
                
            }
            return TreeAndNodes.UpdateOrganizationTreeNodeSecurity(req.NodeID, RequestingMemberID, dt, req.UpdateSequence, req.BlockInheritance );
        }
    }
}

